#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 5.3.22 9:06 AM
# @File    : base_page.py
import time
import os
from selenium.common.exceptions import NoSuchElementException
from utils.log_manager import Logger
from utils.path_manager import Path
from selenium import webdriver
from src.common.browser_manager import Browser
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By


class BasePage(object):

    def __init__(self, driver):
        self.driver = driver
        self.class_name = self.__class__.__name__
        self.logger = Logger(loggername=self.class_name).get_logger()

    # 浏览器最大化
    def max_browser(self):
        self.driver.maximize_window()

    # 设置浏览器的宽和高
    def set_size(self, width, height):
        self.driver.set_window_size(width, height)

    # 关闭浏览器
    def quit_browser(self):
        self.driver.quit()

    # 浏览器前进
    def forward(self):
        self.driver.forward()

    # 浏览器后退
    def back(self):
        self.driver.back()

    def visit(self, url):
        self.driver.get(url)

    def skip_login(self, cookies):
        for cookie in cookies:
            self.driver.add_cookie(cookie)

    def find_ex_element(self, selector):
        element = ''
        if '=>' not in selector:
            return self.driver.find_element_by_id(selector)
        selector_by = selector.split('=>')[0]
        selector_value = selector.split('=>')[1]

        if selector_by == "i" or selector_by == 'id':
            try:
                element = self.driver.find_element_by_id(selector_value)
                self.logger.info("Had find the element {}successful "
                                 "by {} via value: {} ".format(element.text, selector_by, selector_value))
            except NoSuchElementException as e:
                self.logger.error("NoSuchElementException: {}".format(e))
                self.get_windows_img()  # take screenshot
        elif selector_by == "n" or selector_by == 'name':
            element = self.driver.find_element_by_name(selector_value)
        elif selector_by == "c" or selector_by == 'class_name':
            element = self.driver.find_element_by_class_name(selector_value)
        elif selector_by == "l" or selector_by == 'link_text':
            element = self.driver.find_element_by_link_text(selector_value)
        elif selector_by == "p" or selector_by == 'partial_link_text':
            element = self.driver.find_element_by_partial_link_text(selector_value)
        elif selector_by == "t" or selector_by == 'tag_name':
            element = self.driver.find_element_by_tag_name(selector_value)
        elif selector_by == "x" or selector_by == 'xpath':
            try:
                element = self.driver.find_element_by_xpath(selector_value)
                self.logger.info("Had find the element {} successful "
                                 "by {} via value: {} ".format(element.text, selector_by, selector_value))
            except NoSuchElementException as e:
                self.logger.error("NoSuchElementException: {}".format(e))
                self.get_windows_img()
        elif selector_by == "s" or selector_by == 'css_selector':
            element = self.driver.find_element_by_css_selector(selector_value)
        else:
            raise NameError("Please enter a valid type of targeting elements.")

        return element

    # 文本框输入
    def set_value(self, element, text):
        element.clear()
        try:
            element.send_keys(text)
            self.logger.info("Had type {} in inputBox".format(text))
        except NameError as e:
            self.logger.error("Failed to type in input box with {}".format(e))
            self.get_windows_img()

    # 隐式等待
    def wait(self, seconds):
        return self.driver.implicitly_wait(seconds)

    # 强制等待
    def force_wait(self,seconds):
        time.sleep(seconds)

    def wait_visible(self, locate):
        element = WebDriverWait(self.driver, 8).until(EC.presence_of_element_located((By.CLASS_NAME, locate)))
        return element

    # 等待元素可点击
    def element_click_able(self, locate):
        WebDriverWait(self.driver, 1).until(EC.element_to_be_clickable((By.XPATH, locate)))

    def re_refresh(self):
        self.driver.refresh()

    # ---下载设置(Chrome)---
    def download_setting(self, path):

        options = webdriver.ChromeOptions
        prefs = {'profile.default_content_settings.popups': 0,
                 'download.default_directory': path}  # 设置下载路径, 设置为 0 禁止弹出窗口
        options.add_experimental_option('prefs', prefs)
        self.driver = webdriver.Chrome(chrome_options=options)

    # 保存图片
    def get_windows_img(self,filename=''):
        real_file_path = Path().get_picture_path()
        rq = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
        screen_name = rq + '.png'
        if filename:
            real_path = os.path.join(real_file_path,filename)
        else:
            real_path = os.path.join(real_file_path,screen_name)
        try:
            self.driver.get_screenshot_as_file(real_path)
            self.logger.info("Had take screenshot and save to folder file")
            print(screen_name)
        except NameError as e:
            self.logger.error("Failed to take screenpicture! {}".format(e))

    def exec_js(self, js):
        return self.driver.execute_script(js)

    def scroll_until_loaded(self):
        check_height = self.driver.execute_script("return document.body.scrollHeight;")
        print("check_height:"+str(check_height))
        while True:
            self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            try:
                self.wait.until(
                    lambda driver: self.driver.execute_script("return document.body.scrollHeight;") > check_height)
                check_height = self.driver.execute_script("return document.body.scrollHeight;")
            except:
                break

    def get_cookie(self):
        return self.driver.get_cookies()

    def get_page_source(self):
        return self.driver.page_source()

    def action_hold(self, element):
        ActionChains(self.driver).move_to_element(element).perform()

    def action_hold_by_js(self,element):
        js_exec = "var evObj = document.createEvent('MouseEvents');"
        "evObj.initMouseEvent(\"mouseover\",true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);"
        "arguments[0].dispatchEvent(evObj);"
        self.driver.execute_script(js_exec, element)